package com.aloha.auth.support;

import com.aloha.auth.utils.UserHolder;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * @author zhdai
 * @date 2023/11/10 8:34
 */
public class AuthUtils {

    public static boolean check(CheckMode mode, List<String> needPerms) {
        if (mode == CheckMode.AND) {
            return AuthUtils.hasPermAnd(needPerms);
        } else {
            return AuthUtils.hasPermOr(needPerms);
        }
    }

    public static boolean hasPerm(String needPerms) {
        return hasPermAnd(needPerms);
    }

    public static boolean hasPermAnd(List<String> needPerms) {
        List<String> curPerms = getPermsList();
        for (String needPerm : needPerms) {
            if (!hasElem(needPerm, curPerms)) {
                return false;
            }
        }
        return true;
    }

    public static boolean hasPermAnd(String... needPerms) {
        return hasPermAnd(Arrays.asList(needPerms));
    }

    public static boolean hasPermOr(List<String> needPerms) {
        List<String> curPerms = getPermsList();
        for (String needPerm : needPerms) {
            if (hasElem(needPerm, curPerms)) {
                return true;
            }
        }
        return false;
    }

    public static boolean hasPermOr(String... needPerms) {
        return hasPermOr(Arrays.asList(needPerms));
    }

    // 判断list中是否有elem
    private static boolean hasElem(String elem, List<String> list) {
        // 空集合直接返回false
        if (list == null || list.size() == 0) {
            return false;
        }

        // 先尝试一下简单匹配，如果可以匹配成功则无需继续模糊匹配
        if (list.contains(elem)) {
            return true;
        }

        // 开始模糊匹配
        for (String pattern : list) {
            if (vagueMatch(pattern, elem)) {
                return true;
            }
        }

        // 走出for循环说明没有一个元素可以匹配成功
        return false;
    }

    /**
     * 获取当前用户的所有权限
     */
    public static List<String> getPermsList() {
        return new ArrayList<>(Optional.ofNullable(UserHolder.getUser().getPerms()).orElse(new ArrayList<>()));
    }

    private static boolean vagueMatch(String pattern, String str) {
        // 两者均为 null 时，直接返回 true
        if (pattern == null && str == null) {
            return true;
        }
        // 两者其一为 null 时，直接返回 false
        if (pattern == null || str == null) {
            return false;
        }
        // 如果表达式不带有*号，则只需简单equals即可
        if (!pattern.contains("*")) {
            return pattern.equals(str);
        }
        // 深入匹配
        return vagueMatchMethod(pattern, str);
    }

    private static boolean vagueMatchMethod(String pattern, String str) {
        int m = str.length();
        int n = pattern.length();
        boolean[][] dp = new boolean[m + 1][n + 1];
        dp[0][0] = true;
        for (int i = 1; i <= n; ++i) {
            if (pattern.charAt(i - 1) == '*') {
                dp[0][i] = true;
            } else {
                break;
            }
        }
        for (int i = 1; i <= m; ++i) {
            for (int j = 1; j <= n; ++j) {
                if (pattern.charAt(j - 1) == '*') {
                    dp[i][j] = dp[i][j - 1] || dp[i - 1][j];
                } else if (str.charAt(i - 1) == pattern.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1];
                }
            }
        }
        return dp[m][n];
    }
}
